package cn.hyatt.core.dto;

import lombok.Getter;
import lombok.Setter;

import java.io.Serial;
import java.io.Serializable;

/**
 * 统一返回结构体
 *
 * @author hyatt
 */
@Getter
@Setter
public class R<DATA> implements Serializable {
    @Serial
    private static final long serialVersionUID = 42L;

    /**
     * 消息
     */
    private String message;

    /**
     * 状态码
     */
    private Integer code;

    /**
     * 状态
     */
    private Boolean status;

    /**
     * 数据
     */
    private DATA data;

    // 私有化构造方法
    private R(String message, Integer code, Boolean status, DATA data) {
        this.message = message;
        this.code = code;
        this.status = status;
        this.data = data;
    }


    /**
     * 操作成功-无数据
     *
     * @param <DATA> 返回数据类型
     * @return 统一返回结构体
     */
    public static <DATA> R<DATA> ok() {
        return new R<>("操作成功", 200, true, null);
    }

    /**
     * 操作成功-返回数据
     *
     * @param data   数据
     * @param <DATA> 返回数据类型
     * @return 统一返回结构体
     */
    public static <DATA> R<DATA> ok(DATA data) {
        return new R<>("操作成功", 200, true, data);
    }

    /**
     * 操作成功-返回数据
     *
     * @param message 消息内容
     * @param data    数据
     * @param <DATA>  返回数据类型
     * @return 统一返回结构体
     */
    public static <DATA> R<DATA> ok(String message, DATA data) {
        return new R<>(message, 200, true, data);
    }


    /**
     * 操作失败
     *
     * @param <DATA> 返回数据类型
     * @return 统一返回结构体
     */
    public static <DATA> R<DATA> fail() {
        return new R<>("操作失败", 400, false, null);
    }

    /**
     * 操作失败
     *
     * @param message 消息内容
     * @param <DATA>  返回数据类型
     * @return 统一返回结构体
     */
    public static <DATA> R<DATA> fail(String message) {
        return new R<>(message, 400, false, null);
    }

    /**
     * 操作失败 - 自定义消息内容和状态码
     *
     * @param message 消息内容
     * @param code    状态码
     * @param <DATA>  返回数据类型
     * @return 统一返回结构体
     */
    public static <DATA> R<DATA> fail(String message, Integer code) {
        return new R<>(message, code, false, null);
    }
}
